package com.example.k8s.hello.service.sys.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.k8s.hello.common.utils.CopyUtils;
import com.example.k8s.hello.bean.sys.query.SysUserKeyQuery;
import com.example.k8s.hello.service.sys.dao.SysMenuDao;
import com.example.k8s.hello.service.sys.dao.SysUserDao;
import com.example.k8s.hello.service.sys.service.SysRoleService;
import com.example.k8s.hello.service.sys.service.SysUserRoleService;
import com.example.k8s.hello.service.sys.service.SysUserService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import com.example.k8s.hello.common.bean.Page;
import com.example.k8s.hello.common.utils.StpExtendUtil;
import com.example.k8s.hello.bean.sys.entity.SysMenuEntity;
import com.example.k8s.hello.bean.sys.entity.SysUserEntity;
import com.example.k8s.hello.bean.sys.entity.SysUserRoleEntity;
import com.example.k8s.hello.bean.sys.form.SysUserAddForm;
import com.example.k8s.hello.bean.sys.form.SysUserUpdateForm;
import com.example.k8s.hello.bean.sys.query.SysUserQuery;
import com.example.k8s.hello.bean.sys.vo.SysUserVo;
import com.example.k8s.hello.bean.sys.constant.SysConstant;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.InputStream;
import java.util.*;


/**
 * 系统用户
 *
 * @author Mark sunlightcs@gmail.com
 */
@Service
@RequiredArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {
	private final SysUserRoleService sysUserRoleService;
	private final SysRoleService sysRoleService;
	private final SysMenuDao sysMenuDao;

	@Override
	public Page<SysUserVo> queryPage(SysUserQuery query, Page page) {
//		LambdaQueryWrapper<SysUserEntity> wrapper = Wrappers.lambdaQuery(SysUserEntity.class)
//				.like(StringUtils.isNotBlank(query.getUsername()), SysUserEntity::getUsername, query.getUsername()
////						.eq(!StpExtendUtil.ifAdmin(),SysUserEntity::getCreateUserId, StpExtendUtil.getUserId())
//				);
//
//		Long roleId = query.getRoleId();
//		if (roleId != null) {
//			List<Long> userIds = sysUserRoleService.queryUserIdList(roleId);
//			if (CollectionUtils.isEmpty(userIds)) {
//				return page;
//			}
//			wrapper.in(SysUserEntity::getUserId, userIds);
//		}
//
//		return this.page(page, wrapper);
		return this.baseMapper.queryVoPage(page, query);
	}

	@Override
	public List<String> queryAllPerms(Long userId) {
		return baseMapper.queryAllPerms(userId);
	}

	@Override
	public List<Long> queryAllMenuId(Long userId) {
		return baseMapper.queryAllMenuId(userId);
	}

	@Override
	public SysUserEntity queryByUserName(String username) {
		return baseMapper.queryByUserName(username);
	}

	@Override
	@Transactional
	public void saveUser(SysUserAddForm form) {
		SysUserEntity user = CopyUtils.copy(form, SysUserEntity.class);

		user.setPassword(BCrypt.hashpw(user.getPassword()));
		this.save(user);
		
		//检查角色是否越权
		checkRole(user);
		
		//保存用户与角色关系
		sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
	}

	@Override
	@Transactional
	public void update(SysUserUpdateForm form) {
		SysUserEntity user = CopyUtils.copy(form, SysUserEntity.class);

		if(StringUtils.isBlank(user.getPassword())){
			user.setPassword(null);
		}else{
			user.setPassword(BCrypt.hashpw(user.getPassword()));
		}
		this.updateById(user);
		
		//检查角色是否越权
		checkRole(user);
		
		//保存用户与角色关系
		sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
	}

	@Override
	@Transactional
	public void deleteBatch(Long[] userId) {
		if (userId.length < 1) {
			return;
		}

		this.removeByIds(Arrays.asList(userId));

		sysUserRoleService.remove(Wrappers.lambdaQuery(SysUserRoleEntity.class).in(SysUserRoleEntity::getUserId, userId));
	}

	@Override
	public boolean updatePassword(Long userId, String password, String newPassword) {
		SysUserEntity userEntity = new SysUserEntity();
		userEntity.setPassword(newPassword);
		return this.update(userEntity,
				Wrappers.lambdaQuery(SysUserEntity.class).eq(SysUserEntity::getUserId, userId)
						.eq(SysUserEntity::getPassword, password));
	}
	
	/**
	 * 检查角色是否越权
	 */
	private void checkRole(SysUserEntity user){
		if(CollectionUtils.isEmpty(user.getRoleIdList())){
			return;
		}

		//如果不是超级管理员，则需要判断用户的角色是否自己创建
		if(StpExtendUtil.ifAdmin()){
			return;
		}
		
		//查询用户创建的角色列表
		List<Long> roleIdList = sysRoleService.queryRoleIdList(StpExtendUtil.getUserId());

		//判断是否越权
		if(!roleIdList.containsAll(user.getRoleIdList())){
			throw new RuntimeException("新增用户所选角色，不是本人创建");
		}
	}

	@Override
	public Set<String> getUserPermissions(long userId) {
		List<String> permsList;

		//系统管理员，拥有最高权限
		if(userId == SysConstant.SUPER_ADMIN){
			List<SysMenuEntity> menuList = sysMenuDao.selectList(null);
			permsList = new ArrayList<>(menuList.size());
			for(SysMenuEntity menu : menuList){
				permsList.add(menu.getPerms());
			}
		}else{
			permsList = queryAllPerms(userId);
		}
		//用户权限列表
		Set<String> permsSet = new HashSet<>();
		for(String perms : permsList){
			if(StringUtils.isBlank(perms)){
				continue;
			}
			permsSet.addAll(Arrays.asList(perms.trim().split(",")));
		}
		return permsSet;
	}

	@Override
	public Integer batchImport(InputStream inputStream) {
//		// 数据库内学生集合
//		Map<String, String> userMap = list(Wrappers.lambdaQuery(SysUserEntity.class).select(SysUserEntity::getUsername, SysUserEntity::getNickname))
//				.stream().collect(Collectors.toMap(SysUserEntity::getUsername, SysUserEntity::getNickname));
//
//		// excel内需要新增的学生集合
//		HashMap<String, SysUserImportForm> excelMap = new HashMap<>();
//
//		AtomicInteger index = new AtomicInteger(1);
//
//		ArrayList<SysUserEntity> list = new ArrayList<>();
//
//		EasyExcel.read(inputStream, SysUserImportForm.class, new PageReadListener<SysUserImportForm>(dataList -> {
//			for (SysUserImportForm form : dataList) {
//				int i = index.incrementAndGet();
//
//				form.setLineIndex(i);
//
//				String username = form.getUsername();
//				String nickname = form.getNickname();
//
//				ApiExEnum.A0010.assertTrue(StringUtils.isNotBlank(username), "第" + i + "行学号不完整");
//				ApiExEnum.A0010.assertTrue(StringUtils.isNotBlank(nickname), "第" + i + "行姓名不完整");
//
//				if (!userMap.containsKey(username) && !excelMap.containsKey(username)) {
//					excelMap.put(username, form);
//
//					list.add(form.buildUser());
//
//				} else {
//					if (userMap.containsKey(username) && !nickname.equals(userMap.get(username))) {
//						ApiExEnum.A0010.thrown("第" + i + "行学号姓名和已有数据冲突");
//					}
//
//					SysUserImportForm conflictForm = excelMap.get(username);
//					if (conflictForm != null && !nickname.equals(conflictForm.getNickname())) {
//						ApiExEnum.A0010.thrown("第" + i + "行学号姓名和第" + conflictForm.getLineIndex() + "数据冲突");
//					}
//				}
//			}
//		})).sheet().doRead();
//
//		saveBatch(list);
//
//		sysUserRoleService.saveBatch(list.stream().map(user ->
//						new SysUserRoleEntity()
//								.setUserId(user.getUserId())
//								.setRoleId((long) SysConstant.EXAM_ROLE))
//				.toList());
//
//		return list.size();
		return 0;
	}

	@Override
	public void templateDownload() {
//		try {
//			List<SysUserImportForm> list = Arrays.asList(new SysUserImportForm("1111", "广志"));
//
//			HttpServletResponse response = HttpContextUtils.getResponse();
//
//			// 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
//			response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
//			response.setCharacterEncoding("utf-8");
//
//			// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
//			String fileName = URLEncoder.encode("导入模板.xlsx", "UTF-8").replaceAll("\\+", "%20");
//			response.setHeader("Content-disposition", "attachment;filename=" + fileName);
//			EasyExcel.write(response.getOutputStream(), SysUserImportForm.class).sheet().doWrite(list);
//		} catch (IOException e) {
//			ApiExEnum.B0002.thrown(e, "导入模板下载报错");
//		}
	}

	@Override
	public List<Long> queryUserIds(SysUserKeyQuery query) {
		return baseMapper.selectList(Wrappers.lambdaQuery(SysUserEntity.class)
						.select(SysUserEntity::getUserId)
						.and(StringUtils.isNoneBlank(query.getKey()), q -> q.like(SysUserEntity::getUsername, query.getKey())
								.or()
								.like(SysUserEntity::getNickname, query.getKey())))
				.stream().map(SysUserEntity::getUserId).toList();
	}

}